package com.billdowney.util;

import java.sql.Time;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import com.billdowney.util.regex.MatcherUtil;

/**
 * @ClassName: DateUtil
 * @Description: 日期工具类
 * @author 超级小富翁 - BillDowney
 * @date 2018年3月28日 上午11:18:06
 */
public class DateUtil {

	// 字母 含义 示例
	// y Year 1996;96 哪一年
	// M Month in year J uly;Jul;07 一年中的哪一月
	// w Week in year 27 一年中的第几个星期
	// W Week in month 2 一个月中的第几个星期
	// D Day in year 189 一年中的第几天
	// d Day in month 10 一个月中的第几天
	// H Hour in day (0-23) 0 一天中的第几个小时（24小时制）
	// h Hour in am/pm (1-12) 12 一天中上午、下午的第几个小时（12小时制）
	// m Minute in hour 30 一个小时中的第几分钟
	// s Second in minute 55 一分钟的第几秒
	// S Millisecond 978 毫秒数

	private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
	private static final String dateShortFormat = "yyyy-MM-dd";
	private static final String dateFullFormat = "yyyy-MM-dd HH:mm:ss.SSS";
	private static final String timeFormat = "HH:mm:ss";
	private static final String yearFormat = "yyyy";
	private static final String monthFormat = "MM";
	private static final String dayFormat = "dd";
	private static final String hourFormat = "HH";
	private static final String minuteFormat = "mm";
	private static final String secondFormat = "ss";
	private static final String quartzCronFormat = "ss mm HH dd MM ? yyyy";

	/**
	 * @Description: 传入字符串日期和格式化规则来获取Date类
	 * @param strDate 字符串日期
	 * @param sdf     格式化规则
	 * @return 格式化好的Date类型
	 * @author: 超级小富翁 - BillDowney
	 * @throws ParseException
	 * @date: 2018年3月28日 上午11:19:52
	 */
	public static Date getDateByFormat(String strDate, String format) throws ParseException {
		Date date = null;
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		date = sdf.parse(strDate);
		return date;
	}

	/**
	 * @Description: 传入日期类型和格式化规则来返回字符串日期
	 * @param date   传入的日期类型
	 * @param format 格式化规则
	 * @return 格式化过后的字符串
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2018年3月28日 下午12:00:45
	 */
	public static String getDateStrByFormat(Date date, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(date);
	}

	/**
	 * @Description: 传入时间获取时间字符串
	 * @param date 需要转换成字符串的时间类型
	 * @return 转换成的字符串
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2018年10月4日 下午7:02:11
	 */
	public static String getDateStr(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		return sdf.format(date);
	}

	/**
	 * 传入时间获取时间字符串
	 * 
	 * @param date 需要转换成字符串的时间类型
	 * @return 转换成的字符串` 
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2019年3月29日 上午11:26:57
	 */
	public static String getDateShortStr(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(dateShortFormat);
		return sdf.format(date);
	}

	/**
	 * @Description: 获取时间字符串，包含毫秒
	 * @param date 需要转换成字符串的时间类型
	 * @return 转换成的字符串
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2018年10月4日 下午8:14:34
	 */
	public static String getDateFullStr(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(dateFullFormat);
		return sdf.format(date);
	}

	/**
	 * @Description: 传入时间类型和格式化规则来返回字符串时间
	 * @param time   传入的时间类型
	 * @param format 格式化规则
	 * @return 格式化过后的字符串
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2018年3月28日 下午12:02:14
	 */
	public static String getTimeStrByFormat(Time time, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(time);
	}

	/**
	 * @Description: 获得当前时间
	 * @return
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2018年3月28日 上午11:24:57
	 */
	public static String getCurrentTimeStr() {
		SimpleDateFormat sdf = new SimpleDateFormat(timeFormat);
		return sdf.format(new Date());
	}

	/**
	 * @Description: 获得当前日期
	 * @return
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2018年3月28日 上午11:25:01
	 */
	public static String getCurrentDate() {
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		return sdf.format(new Date());
	}

	/**
	 * @Description: 获取当前年
	 * @return
	 * @author: 唐路钧
	 * @date: 2018年9月6日 下午6:29:59
	 */
	public static String getCurrentYear() {
		SimpleDateFormat sdf = new SimpleDateFormat(yearFormat);
		return sdf.format(new Date());
	}

	/**
	 * @Description: 获取当前月份
	 * @return
	 * @author: 唐路钧
	 * @date: 2018年9月6日 下午6:33:04
	 */
	public static String getCurrentMonth() {
		SimpleDateFormat sdf = new SimpleDateFormat(monthFormat);
		return sdf.format(new Date());
	}

	/**
	 * @Description: 获取当前天数
	 * @return
	 * @author: 唐路钧
	 * @date: 2018年9月6日 下午6:33:04
	 */
	public static String getCurrentDay() {
		SimpleDateFormat sdf = new SimpleDateFormat(dayFormat);
		return sdf.format(new Date());
	}

	/**
	 * @Description: 获取当前小时，24小时制
	 * @return
	 * @author: 唐路钧
	 * @date: 2018年9月6日 下午6:33:04
	 */
	public static String getCurrentHour() {
		SimpleDateFormat sdf = new SimpleDateFormat(hourFormat);
		return sdf.format(new Date());
	}

	/**
	 * @Description: 获取当前分钟
	 * @return
	 * @author: 唐路钧
	 * @date: 2018年9月6日 下午6:33:04
	 */
	public static String getCurrentMinute() {
		SimpleDateFormat sdf = new SimpleDateFormat(minuteFormat);
		return sdf.format(new Date());
	}

	/**
	 * @Description: 获取当前秒
	 * @return
	 * @author: 唐路钧
	 * @date: 2018年9月6日 下午6:33:04
	 */
	public static String getCurrentSecond() {
		SimpleDateFormat sdf = new SimpleDateFormat(secondFormat);
		return sdf.format(new Date());
	}

	/**
	 * @Description: 传入字符串时间，获取Time类型
	 * @param strTime 传入的时间字符串
	 * @return 转化后的Time类型
	 * @author: 超级小富翁 - BillDowney
	 * @throws ParseException
	 * @date: 2018年3月28日 上午11:28:37
	 */
	public static Time getTimeByStr(String strTime) throws ParseException {
		Date d = getDateByFormat(strTime, timeFormat);
		return new Time(d.getTime());
	}

	/**
	 * @Description: 该函数的功能描述
	 * @param strTime 字符串日期
	 * @param sdf     格式化规则
	 * @return 转化后的Time类型
	 * @throws ParseException
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2018年3月28日 上午11:37:40
	 */
	public static Time getTimeByStrAndFormat(String strTime, String sdf) throws ParseException {
		return new Time(getDateByFormat(strTime, sdf).getTime());
	}

	/**
	 * @Description: 该函数的功能描述
	 * @param strDate
	 * @return
	 * @throws ParseException
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2018年3月28日 上午11:39:24
	 */
	public static Date getDateByStr(String strDate) throws ParseException {
		if (MatcherUtil.matcher("[0-9]{2}:[0-9]{2}:[0-9]{2}$", strDate) == false) {
			strDate += " 00:00:00";
		}
		return getDateByFormat(strDate, dateFormat);
	}

	/**
	 * @Description: 获取当前时间的时间戳
	 * @return long型的时间戳
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2018年3月28日 下午9:18:32
	 */
	public static Time getCurrentTime() {
		try {
			return getTimeByStr(getCurrentTimeStr());
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * @Description: 该函数的功能描述
	 * @param smdate 较小的时间
	 * @param bdate  较大的时间
	 * @return 相差天数
	 * @throws ParseException
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2018年3月30日 上午11:32:55
	 */
	public static int daysBetween(Date smdate, Date bdate) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		smdate = sdf.parse(sdf.format(smdate));
		bdate = sdf.parse(sdf.format(bdate));
		Calendar cal = Calendar.getInstance();
		cal.setTime(smdate);
		long time1 = cal.getTimeInMillis();
		cal.setTime(bdate);
		long time2 = cal.getTimeInMillis();
		long between_days = (time2 - time1) / (1000 * 3600 * 24);
		return Integer.parseInt(String.valueOf(between_days));
	}

	/**
	 * @Description: 传入日期获得时间类型
	 * @param date 时间类型
	 * @return
	 * @author: 超级小富翁 - BillDowney
	 * @throws ParseException
	 * @date: 2018年3月30日 下午5:37:41
	 */
	public static Time getTimeByDate(Date date) throws ParseException {
		return getTimeByStr(getDateStrByFormat(date, timeFormat));
	}

	/**
	 * @Description: 通过时间类来获取quartz时间调度字符串
	 * @param date 时间类
	 * @return 格式化的字符串
	 * @author: 超级小富翁 - BillDowney
	 * @date: 2018年9月23日 下午8:50:10
	 */
	public static String getQuartzCron(Date date) {
		return getDateStrByFormat(date, quartzCronFormat);
	}
}
